package com.mashibing.tank;

import com.mashibing.tank.net.TankJoinMsg;
import lombok.Data;

import java.awt.*;
import java.util.Random;
import java.util.UUID;

/**
 * @description:
 * @author: 余希瑶
 * @date: 2021年06月18日 10:20
 * @version:1.0
 */
@Data
public class Tank extends AbstractGameObject {
    public static int WIDTH = ResourceMgr.goodTankU.getWidth();

    public static int HEIGHT = ResourceMgr.goodTankU.getHeight();

    private UUID id = UUID.randomUUID();

    //记录键盘是否被按下的变量
    public static final int SPEED = 5;
    private int x, y;
    private Dir dir;
    private boolean bL, bU, bR, bD;
    //是否移动
    private boolean moving = true;
    private Group group;
    private boolean live = true;

    //设定坦克的宽度和高度
    private int width, height;
    //记录碰撞窗口前的 x,y
    private int oldx, oldy;

    Rectangle rect = new Rectangle();

    public Tank(TankJoinMsg tankJoinMsg) {
        this.x = tankJoinMsg.getX();
        this.y = tankJoinMsg.getY();
        this.dir = tankJoinMsg.getDir();
        this.moving = tankJoinMsg.isMoving();
        this.group = tankJoinMsg.getGroup();
        this.id = tankJoinMsg.getId();

        oldx = x;
        oldy = y;

        this.width = ResourceMgr.badTankU.getWidth();
        this.height = ResourceMgr.badTankU.getHeight();

        rect.x = this.x;
        rect.y = this.y;
        rect.width = WIDTH;
        rect.height = HEIGHT;
    }

    public Tank(int x, int y, Dir dir, Group group) {
        this.x = x;
        this.y = y;
        this.dir = dir;
        this.group = group;

        oldx = x;
        oldy = y;

        this.width = ResourceMgr.badTankU.getWidth();
        this.height = ResourceMgr.badTankU.getHeight();

        rect.x = this.x;
        rect.y = this.y;
        rect.width = WIDTH;
        rect.height = HEIGHT;
    }

    public void paint(Graphics g) {

        if (!this.isLive()) {
            return;
        }

        switch (dir) {
            case L:
                g.drawImage(ResourceMgr.badTankL, x, y, null);
                break;
            case U:
                g.drawImage(ResourceMgr.badTankU, x, y, null);
                break;
            case R:
                g.drawImage(ResourceMgr.badTankR, x, y, null);
                break;
            case D:
                g.drawImage(ResourceMgr.badTankD, x, y, null);
                break;
        }


        move();
    }


    private void setMainDir() {
        //all dir keys are released, tank shouId be stop


        if (!bL && !bU && !bR && !bD) {
            moving = false;
        } else {
            //any dir key is pressed, tank should be moving
            moving = true;
            if (bL && !bU && !bR && !bD) {
                dir = Dir.L;
            }
            if (!bL && bU && !bR && !bD) {
                dir = Dir.U;
            }
            if (!bL && !bU && bR && !bD) {
                dir = Dir.R;
            }
            if (!bL && !bU && !bR && bD) {
                dir = Dir.D;
            }

            /*// 左上
            if (bL && bU && !bR && !bD) {
                dir =Dir.LU;
            }
            // 左下
            if (bL && !bU && !bR && bD) {
                dir =Dir.LD;
            }
            // 右上
            if (!bL && !bU && bR && bD) {
                dir =Dir.RU;
            }
            // 右下
            if (!bL && bU && bR && !bD) {
                dir =Dir.RD;
            }*/
        }

    }

    private void move() {
        if (!moving) return;
        oldx = x;
        oldy = y;


        switch (dir) {
            case L:
                x -= SPEED;
                break;
            case U:
                y -= SPEED;
                break;
            case R:
                x += SPEED;
                break;
            case D:
                y += SPEED;
                break;
        }
        boundsCheck();

        //update rect
        rect.x = this.x;
        rect.y = this.y;

        randomDir();
        if (r.nextInt(100) > 90) {
            fire();
        }

    }

    private void boundsCheck() {
        if (x < 0 || y < 30 || x + width > TankFrame.GAME_WIDTH || y + height > TankFrame.GAME_HEIGHT) {
            this.back();
        }
    }

    public void back() {
        this.x = oldx;
        this.y = oldy;
    }


    private Random r = new Random();

    private void randomDir() {
        if (r.nextInt(100) > 90) {
            this.dir = Dir.randomDir();
        }
    }


    private void fire() {
        int bX = this.x + Tank.WIDTH / 2 - Bullet.WIDTH / 2;
        int bY = this.y + Tank.HEIGHT / 2 - Bullet.HEIGHT / 2;

        Bullet b = new Bullet(this.id, bX, bY, this.dir, this.group, TankFrame.INSTANCE);

        TankFrame.INSTANCE.getGm().objects.add(b);
    }

    public void die() {
        this.setLive(false);
        TankFrame.INSTANCE.getGm().add(new Explode(x, y));
    }
}
